home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Electronic Clipper 1995 April
/
Electronic Clipper 1995-04.iso
/
pc
/
pc_users
/
ideasrc
/
setup
/
pviewer
/
pictwnd.c
< prev
next >
Wrap
Text File
|
1993-04-17
|
101KB
|
2,392 lines
// ---------------------------------------------------------------------
//
// PictWnd.c - Picture Viewer - QuickTime for Windows
//
// Version 1.0
//
// (c) 1988-1992 Apple Computer, Inc. All Rights Reserved.
//
// ---------------------------------------------------------------------
// Includes
// --------
#include <Windows.H> // Required by Windows
#include <commdlg.h> // Required for PRINTDLG struct
#include <stdio.h> // Required for sprintf routine
#include <stdlib.h> // Required for fullpath routine
#include <sys\types.h> // Required for stat.h
#include <sys\stat.h> // Required for _stat routine
#include <qtw.h> // Interface to QuickTime
#include <qtole.h> // Interface to qtole dll
#include "common.h" // Interface to common.c
#include "viewer.h" // Interface to other *.c files
#include "viewer.hr" // Defines used in *.rc files
#include "picture.h" // Interface to child window processing
// Constants
// ---------
#define GETINFOPICTUREPROP "Picture" // Used in initializing info dialog
#define SIZE_COLOR_TABLE ( 256 * sizeof( RGBQUAD ))
// Message-Persistent Data
// -----------------------
static struct // Hungarian notation: g
{ WORD wPictureCount; // Used during enumeration for
// duplication checking
BOOL bCreating; // " " "
HWND hwndFirstDup; // " " "
HICON hpictIcon; // Picture wnd icon
HPALETTE hpalCurrentSystem; // Current system palette
RECT rcSelection; // Selection rect
} g;
// Macros
// ----------------------------
#define ISKEYDOWN( vKey ) ( GetKeyState( (int) (vKey) ) < 0 )
// Next macro is from windowsx.h
#define GlobalPtrHandle(lp) \
( (HGLOBAL) LOWORD( GlobalHandle( SELECTOROF( lp ))))
// Exported callback function
// ----------------------------
BOOL __export CALLBACK GetInfoDlgProc (HWND, UINT, WPARAM, LPARAM);
BOOL __export CALLBACK CheckDupEnumProc (HWND, LPARAM);
// Internal Function Declarations
// ------------------------------
static LONG NEAR ViewerPictureCreate (HWND, LPARAM );
static LONG NEAR ViewerEditCommands (HWND, WPARAM, WORD);
static LONG NEAR ViewerImageCommands (HWND, WPARAM, WORD);
static LONG NEAR PrintPicture (HWND, LPPRINTDLG);
static VOID NEAR FillPictureInfo (HWND, NPPICTUREDATA);
static VOID NEAR UpdateInfoFileName (HWND, NPPICTUREDATA);
static VOID NEAR UpdateInfoCurrentSize (HWND, NPPICTUREDATA);
static LONG NEAR InitializePopupMenus (HWND, HMENU, int);
static LONG NEAR PaintThePicture (HWND);
static LONG NEAR PaintTheIcon (HWND);
static LONG NEAR KeyDownMessage (HWND, WPARAM, LPARAM);
static BOOL NEAR BuildIconBitmap (HWND, NPPICTUREDATA);
static BOOL NEAR InitSelection (HWND, POINT);
static VOID NEAR MoveTheSelectRect (HWND, POINT);
static VOID NEAR EndTheSelection (HWND);
static VOID NEAR DrawSelectionRect (HWND, HDC, NPPICTUREDATA);
static VOID NEAR SetOptionsDefaults (HWND, NPPICTUREDATA);
static VOID NEAR PopulateOptionsStruct (HWND, NPPICTUREDATA);
// Function: ViewerPictureWndProc - Viewer picture Window Procedure
// --------------------------------------------------------------------
// Parameters: As required by Microsoft Windows
//
// Returns: Via DefMDIChildProc
// --------------------------------------------------------------------
LONG __export CALLBACK ViewerPictureWndProc
(HWND hwndPicture, UINT message, WPARAM wParam, LPARAM lParam)
{NPPICTUREDATA pPictureData; // Temp -> to picture data struct
HPICTUREDATA hPictureData; // Temp handle to picture data
WNDENUMPROC lpfnEnumPictures; // -> enumeration proc
NPPICTUREDATA pFirstPictureData; // Temp -> to picture data
// struct. Used during duplication
// processing
HDC hdc; // Window hdc
HPALETTE hpalSave; // Prev palette
POINT ptCursor; // Cursor position used in grow box
LPNCCALCSIZE_PARAMS lpncsp; // -> NCCCALCSIZE_PARAMS struct
LPQTOLE_OLEDATA lpOleData; // -> ole data
static BOOL bDragging; // Flag set when using grow box
static BOOL bSelecting; // Flag set when making a selection
switch( message )
{case WM_CREATE:
// Load picture frame icon used by all instances
if( !g.hpictIcon )
g.hpictIcon = LoadIcon( ViewerQueryResources(),
MAKEINTRESOURCE( VIEWER_PICT_ICON ));
return ViewerPictureCreate( hwndPicture , lParam );
case WM_SIZE:
// Turn off the max size limits set during
// WM_NCLBUTTONDOWN processing
if( bDragging )
{LimitTheDragSize( hwndPicture, bDragging = FALSE );
}
// This routine also updates scrolling parameters
ResizeKids( hwndPicture, LOWORD( lParam ), HIWORD( lParam ));
break; // Break to DefMDIChildProc
// We don't use the CS_HREDRAW | CS_VREDRAW so we need to
// tell when to repaint the entire picture. We repaint the whole
// thing if the UL corner moves or either of the scroll
// bars is enabled.
case WM_NCCALCSIZE:
if( wParam )
{lpncsp = (LPNCCALCSIZE_PARAMS) lParam;
if( !( pPictureData =
(NPPICTUREDATA) GetWindowWord( hwndPicture, 0 )) ||
( lpncsp->rgrc[0].left != lpncsp->rgrc[1].left ) ||
( lpncsp->rgrc[0].top != lpncsp->rgrc[1].top ) ||
IsWindowEnabled( pPictureData->spmsHScroll.hwnd ) ||
IsWindowEnabled( pPictureData->spmsVScroll.hwnd ))
{InvalidateRect( hwndPicture, NULL, FALSE );
}
else if( ( lpncsp->rgrc[0].right > lpncsp->rgrc[1].right ) ||
( lpncsp->rgrc[0].bottom > lpncsp->rgrc[1].bottom ))
{ // Paint out the grow box. At this point, the grow box rect
// still contains the old rect since this message occurs
// before the WM_SIZE message
InvalidateRect( hwndPicture,
&pPictureData->rcGrowBox, FALSE );
}
}
break; // Break to DefMDIChildProc
// This tells windows to treat the grow box like the
// bottom right window frame
case WM_NCHITTEST:
if( !IsZoomed( hwndPicture ))
{ptCursor = MAKEPOINT( lParam );
ScreenToClient( hwndPicture, &ptCursor );
if( IsInGrowBox( hwndPicture, ptCursor ))
return HTBOTTOMRIGHT;
}
break; // Break to DefMDIChildProc
// Set the cursor to the arrow cursor in the grow box
// Because of the WM_NCHITTEST processing we do, Windows
// thinks it is in the corner border and will set the
// cursor to the diagonal arrow.
case WM_SETCURSOR:
if( LOWORD( lParam ) == HTBOTTOMRIGHT )
{GetCursorPos( &ptCursor );
ScreenToClient( hwndPicture, &ptCursor );
if( IsInGrowBox( hwndPicture, ptCursor ))
{SetCursor( LoadCursor( NULL, IDC_ARROW ));
return 1L;
}
}
break; // Break to DefMDIChildProc
// Limit the window size so that the grow box resized window
// stays inside the MDI client rect
case WM_NCLBUTTONDOWN:
if( wParam == HTBOTTOMRIGHT )
{ptCursor = MAKEPOINT( lParam );
ScreenToClient( hwndPicture, &ptCursor );
if( IsInGrowBox( hwndPicture, ptCursor ))
{LimitTheDragSize( hwndPicture, bDragging = TRUE );
}
}
break; // Break to DefMDIChildProc
// WM_LBUTTONDOWN, WM_MOUSEMOVE, WM_LBUTTONUP are used to implement
// grow box resizing of the frame window when the window is maximized
case WM_LBUTTONDOWN:
if( IsZoomed( hwndPicture ) &&
!IsZoomed( ViewerQueryFrameWindow()) &&
IsInGrowBox( hwndPicture, MAKEPOINT( lParam )) &&
( bDragging = InitMaxWndGrowBoxResize
( hwndPicture, MAKEPOINT( lParam ))))
{SetCapture( hwndPicture );
}
else if( bSelecting = InitSelection
( hwndPicture, MAKEPOINT( lParam )))
{SetCapture( hwndPicture );
}
return 0L;
case WM_MOUSEMOVE:
if( bDragging && IsZoomed( hwndPicture ))
{MoveTheFrameRect( hwndPicture, MAKEPOINT( lParam ));
}
else if( bSelecting )
{MoveTheSelectRect( hwndPicture, MAKEPOINT( lParam ));
}
return 0L;
case WM_LBUTTONUP:
if( bDragging && IsZoomed( hwndPicture ))
{EndMaxWndGrowBoxResize( hwndPicture );
bDragging = FALSE;
ReleaseCapture();
}
else if( bSelecting )
{EndTheSelection( hwndPicture );
bSelecting = FALSE;
ReleaseCapture();
}
return 0L;
case WM_NCACTIVATE:
if( !( pPictureData =
(NPPICTUREDATA) GetWindowWord( hwndPicture, 0 )))
break; // Break to DefMDIChildProc
if( (BOOL) wParam )
{ // Set flag to disable the scroll bar processing. Although this
// is only necessary in the case of palettized devices, it is
// done in all cases in order to have a consistent user interface.
// This disabling is necessary in order to avoid a problem with
// simultaneous scrolling and palette switching that leaves a
// portion of the picture incorrectly updated.
// The visual effect of this disabling is that clicking on a
// scroll bar will activate the window but will not cause the
// scolling to actually occur.
pPictureData->bScrollWaitForPaint = TRUE;
// Realize palette if activating and is palettized device
if( ViewerIsPalettized())
{if( pPictureData->hpalPicture &&
( hdc = GetDC( hwndPicture )))
{hpalSave = SelectPalette
( hdc, pPictureData->hpalPicture, 0 );
StoreCurrentSystemPalette
( pPictureData->hpalPicture );
RealizePalette( hdc );
SelectPalette( hdc, hpalSave, 0 );
ReleaseDC( hwndPicture, hdc );
InvalidateRect( hwndPicture, NULL, FALSE );
}
else if( GetUpdateRect( hwndPicture, NULL, FALSE ))
InvalidateRect( hwndPicture, NULL, FALSE );
}
else
{ // Post message to reable scrolling because generally will
// not get a WM_PAINT message. Don't want to use
// InvalidateRect() because it will generate an unnessary
// repaint.
PostMessage( hwndPicture, WM_VIEWER_REENABLESCROLL, 0, 0L );
}
}
break; // Break to DefMDIChildProc
case WM_SYSCOMMAND:
// Each picture needs an icon bitmap. We build it here
// because the window must have first realized the palette.
// This message appears after the WM_NCACTIVATE
// message for this window and before the WM_NCACTIVATE
// for the window that will eventually be activated.
// This bitmap will be created and saved the first time
// the window is iconized
if( ( wParam == SC_MINIMIZE ) &&
( pPictureData =
(NPPICTUREDATA) GetWindowWord( hwndPicture, 0 )) &&
!pPictureData->hbitmapIcon && !pPictureData->lpDIBIconMem )
{BuildIconBitmap( hwndPicture, pPictureData );
}
break; // Break to DefMDIChildProc
case WM_COMMAND:
switch( wParam )
{case VIEWER_EDIT_COPYPICTURE: // edit menu popup
case VIEWER_EDIT_OPTIONS:
case VIEWER_EDIT_CANCELSEL:
return ViewerEditCommands
( hwndPicture, wParam, HIWORD (lParam));
case VIEWER_IMAGE_GETINFO: // image menu popup
case VIEWER_IMAGE_HALFSIZE:
case VIEWER_IMAGE_NORMALSIZE:
case VIEWER_IMAGE_DOUBLESIZE:
return ViewerImageCommands
( hwndPicture, wParam, HIWORD( lParam ));
default:
break; // Break to DefMDIChildProc
}
break;
case WM_KEYDOWN:
return KeyDownMessage( hwndPicture, wParam, lParam );
// WM_USER messages
case WM_VIEWER_PRINTPICTURE:
return PrintPicture( hwndPicture, (LPPRINTDLG) lParam );
case WM_VIEWER_INITPOPUPS:
return InitializePopupMenus
( hwndPicture, (HMENU) wParam, (int) LOWORD( lParam ));
case WM_VIEWER_REENABLESCROLL:
if( pPictureData = (NPPICTUREDATA) GetWindowWord( hwndPicture, 0 ))
pPictureData->bScrollWaitForPaint = FALSE;
return 0L;
// end WM_USER messages
case WM_ERASEBKGND:
// If there is a picture, let it deal with the background in
// WM_PAINT
return ((pPictureData =
(NPPICTUREDATA) GetWindowWord( hwndPicture, 0 )) != NULL );
case WM_HSCROLL:
if( !( pPictureData = (NPPICTUREDATA)
GetWindowWord( hwndPicture, 0 )) ||
pPictureData->bScrollWaitForPaint )
{return 0L;
}
else
{return ProcessHorzScroll
( hwndPicture, (WORD) wParam, LOWORD( lParam ));
}
case WM_VSCROLL:
if( !( pPictureData = (NPPICTUREDATA)
GetWindowWord( hwndPicture, 0 )) ||
pPictureData->bScrollWaitForPaint )
{return 0L;
}
else
{return ProcessVertScroll
( hwndPicture, (WORD) wParam, LOWORD( lParam ));
}
case WM_GETMINMAXINFO:
SetMinMaxInfo( (MINMAXINFO FAR*) lParam );
break; // Break to DefMDIChildProc
case WM_QUERYDRAGICON:
return MAKELONG( g.hpictIcon, 0 );
case WM_PAINT:
if( IsIconic( hwndPicture ))
return PaintTheIcon( hwndPicture );
else
{if( PaintThePicture( hwndPicture ))
{ // Draw picture failed so close window
PostMessage( hwndPicture, WM_CLOSE, 0, 0L );
}
else if( pPictureData = (NPPICTUREDATA)
GetWindowWord( hwndPicture, 0 ))
pPictureData->bScrollWaitForPaint = FALSE;
return 0L;
}
case WM_DESTROY:
if( ( pPictureData = (NPPICTUREDATA)
GetWindowWord( hwndPicture, 0 )) &&
( lpOleData = ViewerQueryOleData()) && lpOleData->lpqtoleServer )
{PopulateOptionsStruct( hwndPicture, pPictureData );
if( !QTOLE_ClosingDocWnd( lpOleData,
(LPQTOLE_OPTIONS) &pPictureData->qtoleOptions ))
return 0L;
}
break; // break to DefMDIChildProc
// Process WM_NCDESTROY instead of WM_DESTROY so that child controls
// get WM_DESTROY messages before the stuff in here get executed
case WM_NCDESTROY:
if( !(pPictureData =
(NPPICTUREDATA) GetWindowWord( hwndPicture, 0 )))
break;
if( pPictureData->hwndGetInfo )
DestroyWindow( pPictureData->hwndGetInfo );
if( pPictureData->phPicture != NULL)
DisposePicture( pPictureData->phPicture );
if( pPictureData->hpalPicture )
DeleteObject( pPictureData->hpalPicture );
if( pPictureData->hbitmapIcon )
DeleteObject( pPictureData->hbitmapIcon );
if( pPictureData->lpDIBIconMem )
{GlobalUnlock( GlobalPtrHandle( pPictureData->lpDIBIconMem ));
GlobalFree( GlobalPtrHandle( pPictureData->lpDIBIconMem ));
}
// Last instance destroys icon stuff
if( ViewerQueryNumPictures() <= 1 )
{if( g.hpictIcon )
{DestroyIcon( g.hpictIcon );
g.hpictIcon = NULL;
}
g.hpalCurrentSystem = NULL;
DestroyGrowBoxBitmap();
}
else // Check for duplicates
{g.wPictureCount = 0;
g.bCreating = FALSE;
g.hwndFirstDup = NULL;
if( lpfnEnumPictures = (WNDENUMPROC) MakeProcInstance
( (FARPROC) CheckDupEnumProc, ViewerQueryInstance()))
{EnumChildWindows( ViewerQueryClientWindow(),
lpfnEnumPictures, MAKELPARAM( hwndPicture, 0 ));
FreeProcInstance( (FARPROC) lpfnEnumPictures );
// if no dups, eliminate :1 on first
// hwndFirstDup is set in CheckDupEnumProc
if( ( g.wPictureCount == 1 ) && g.hwndFirstDup &&
( pFirstPictureData = (NPPICTUREDATA)
GetWindowWord( g.hwndFirstDup, 0 )))
{pFirstPictureData->wDuplicationIndex = 0;
SetWindowText( g.hwndFirstDup,
pFirstPictureData->szPictureName );
}
}
}
LocalUnlock( hPictureData =
(HPICTUREDATA) LocalHandle( pPictureData ));
LocalFree( hPictureData );
SetWindowWord( hwndPicture, 0, 0 ); // Set this to 0 for any
// subsequent messages
SendMessage( ViewerQueryFrameWindow(),
WM_VIEWER_PICTUREDELETED, (WPARAM) hwndPicture, 0L );
break; // break to DefMDIChildProc
}
return DefMDIChildProc( hwndPicture, message, wParam, lParam );
}
// Function: ViewerPictureCreate - process WM_CREATE message
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Handle of picture window
// LPARAM lParam lParam of WM_CREATE message
//
// Returns: 0L if OK, else returns -1L to kill app
// --------------------------------------------------------------------
static LONG NEAR ViewerPictureCreate( HWND hwndPicture, LPARAM lParam )
{NPPICTUREDATA pPictureData; // Temp -> to picture data struct
HPICTUREDATA hPictureData; // Handle to picture data struct
LPMDICREATESTRUCT lpmdicreate; // MDI create struct
struct _stat statbuf; // File statictics struct
char szBuffer[MAX_PATH_LEN]; // Temp buffer
DWORD dwBytes; // File size
OSErr oserr; // Error return
WORD wIDString1; // Resource string id
WORD wIDString2; // Resource string id
POINT ptCorner; // Upper Left corner of pict wnd
RECT rcWindow; // Window rect
int nDiff; // Temp
RECT rcclientClient; // Client rect of MDI client wnd
WORD wWidth; // Width of window
WORD wHeight; // Height of window
WNDENUMPROC lpfnEnumPictures; // -> to enumeration proc
LPSTR lpName; // Temp -> picture name
PicFile picPicFile; // Picture file handle
HDC hdc; // Window hdc
HCURSOR hcursorSave; // Prior cursor
char szCompressor[sizeof(DWORD) + 1]; // compressor type
QTOLE_OPENWND qtoleOpenWnd; // Ole open wnd struct
LPQTOLE_OLEDATA lpOleData; // -> ole data
WORD wZoomIndex; // Initial zoom index
pPictureData = (NPPICTUREDATA) NULL;
szBuffer[0] = '\0';
hcursorSave = NULL;
if( !(hPictureData = (HPICTUREDATA)
LocalAlloc( LPTR, sizeof( PICTUREDATASTRUCT ))))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOMEMORY, NULL, MB_OK );
goto Failed;
}
pPictureData = (NPPICTUREDATA) LocalLock( hPictureData );
SetWindowWord( hwndPicture, 0, (WORD) pPictureData );
// mdi struct filled before call to MDI create in LaunchPictureWnd
lpmdicreate = (LPMDICREATESTRUCT)
((LPCREATESTRUCT) lParam)->lpCreateParams;
lstrcpy( pPictureData->szPictureName, (LPSTR) lpmdicreate->szTitle );
// Strip off and save extension so that name fits better
// on title bar of window
pPictureData->szPictureExt[0] = '\0';
lpName = pPictureData->szPictureName;
while( *lpName )
{if( *lpName == '.' )
{lstrcpy( pPictureData->szPictureExt, lpName );
*lpName = '\0';
SetWindowText( hwndPicture, pPictureData->szPictureName );
break;
}
else
lpName = AnsiNext( lpName );
}
// Open picture file and extract picture
hcursorSave = SetCursor( LoadCursor( NULL, IDC_WAIT ));
// Cache path
lstrcpy( pPictureData->szPicturePath, (LPSTR) lpmdicreate->lParam );
if( OpenPictureFile( pPictureData->szPicturePath,
&picPicFile, OF_READ ))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOOPENFILE, VIEWER_STRING_CAPTION,
MB_OK, (LPSTR) lpmdicreate->szTitle );
goto Failed;
}
pPictureData->phPicture = GetPictureFromFile( picPicFile );
ClosePictureFile( picPicFile );
if( !pPictureData->phPicture )
{if( ( oserr = GetMoviesStickyError()) == noPictureInFile )
wIDString1 = VIEWER_STRING_NOPICINFILE;
else if( oserr == insufficientMemory )
wIDString1 = VIEWER_STRING_NOMEMORY;
else
wIDString1 = VIEWER_STRING_NOGETPIC;
ClearMoviesStickyError();
CommonTellUser( ViewerQueryResources(),
wIDString1, VIEWER_STRING_CAPTION,
MB_OK, (LPSTR) lpmdicreate->szTitle );
goto Failed;
}
// Check for duplicates. Fix up titles if necessary
// Initialize globals used during enumeration
g.wPictureCount = 1;
g.bCreating = TRUE;
if( ( ViewerQueryNumPictures() > 0 ) &&
( lpfnEnumPictures = (WNDENUMPROC) MakeProcInstance
( (FARPROC) CheckDupEnumProc, ViewerQueryInstance())))
{EnumChildWindows( ViewerQueryClientWindow(),
lpfnEnumPictures, MAKELPARAM( hwndPicture, 0 ));
FreeProcInstance( (FARPROC) lpfnEnumPictures );
// Fix up title if duplicate
// Title of 1st dup is fixed up during enum
if( g.wPictureCount > 1 )
{pPictureData->wDuplicationIndex = g.wPictureCount;
wsprintf( szBuffer, "%s:%u",
(LPSTR) pPictureData->szPictureName,
pPictureData->wDuplicationIndex );
SetWindowText( hwndPicture, szBuffer );
}
}
// Get the palette for the picture if the monitor is palettized
// A default palette is returned if the picture does not have a palette
pPictureData->hpalPicture = NULL;
if( ViewerIsPalettized() && ( hdc = GetDC( hwndPicture )))
{pPictureData->hpalPicture =
GetPicturePalette( pPictureData->phPicture );
ReleaseDC( hwndPicture, hdc );
}
// Get file size Note: Need to switch to OEM char set.
// Sizes are displayed in banner bar and in info dialog
AnsiToOem( pPictureData->szPicturePath, szBuffer );
if( (_stat( szBuffer, &statbuf )) == 0 )
{if( statbuf.st_size < 1000L )
{dwBytes = (DWORD) statbuf.st_size;
wIDString1 = VIEWER_STRING_SIZEBYTES;
wIDString2 = VIEWER_STRING_SIZEBYTESONDISK;
}
else
{dwBytes = (DWORD) ( statbuf.st_size / 1000L );
wIDString1 = VIEWER_STRING_SIZEKBYTES;
wIDString2 = VIEWER_STRING_SIZEKBYTESONDISK;
}
LoadString( ViewerQueryResources(),
wIDString1, szBuffer, sizeof( szBuffer ));
wsprintf( pPictureData->szFileSize, szBuffer, dwBytes );
LoadString( ViewerQueryResources(),
wIDString2, szBuffer, sizeof( szBuffer ));
wsprintf( pPictureData->szFileSizeOnDisk, szBuffer, dwBytes );
}
pPictureData->idImageInfo.idSize = sizeof( ImageDescription );
if( GetPictureInfo( pPictureData->phPicture, &pPictureData->idImageInfo ))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOINFO, VIEWER_STRING_CAPTION, MB_OK );
goto Failed;
}
// Picture type
if( pPictureData->idImageInfo.name[0] )
{lstrcpy( pPictureData->szPictType, pPictureData->idImageInfo.name );
}
else
{ // Compressor type is stored as a DWORD. i.e. 'jpeg'
if( pPictureData->idImageInfo.CodecType )
{*((PDWORD) &szCompressor) = pPictureData->idImageInfo.CodecType;
szCompressor[ sizeof(DWORD) ] = '\0';
}
pPictureData->szPictType[0] = '\0';
// Spaces in "raw ", "rle " etc are necessary !!!
if( !pPictureData->idImageInfo.CodecType ||
!lstrcmpi( szCompressor, "raw " ))
wIDString1 = VIEWER_STRING_CODEC_NONE;
else if( !lstrcmpi( szCompressor, "jpeg" ))
wIDString1 = VIEWER_STRING_CODEC_PHOTO;
else if( !lstrcmpi( szCompressor, "rle " ))
wIDString1 = VIEWER_STRING_CODEC_ANIMATION;
else if( !lstrcmpi( szCompressor, "smc " ))
wIDString1 = VIEWER_STRING_CODEC_GRAPHICS;
else if( !lstrcmpi( szCompressor, "rpza" ))
wIDString1 = VIEWER_STRING_CODEC_VIDEO;
else if( !lstrcmpi( szCompressor, "cvid" ))
wIDString1 = VIEWER_STRING_CODEC_CVID;
else
wIDString1 = VIEWER_STRING_CODEC_NONE;
LoadString( ViewerQueryResources(), wIDString1,
pPictureData->szPictType, sizeof( pPictureData->szPictType ));
}
// Adjust resolution for Mac wierdness
if( ( pPictureData->idImageInfo.hRes == -1 ) &&
( pPictureData->idImageInfo.vRes == -1 ))
pPictureData->idImageInfo.hRes =
pPictureData->idImageInfo.vRes = MAKELFIXED( 72, 0 );
else if( pPictureData->idImageInfo.hRes == -1 )
pPictureData->idImageInfo.hRes = pPictureData->idImageInfo.vRes;
else if( pPictureData->idImageInfo.vRes == -1 )
pPictureData->idImageInfo.vRes = pPictureData->idImageInfo.hRes;
// Initialize this to something impossible so that
// size checking tests in ZoomPicture, etc will work
// during startup
pPictureData->zsZoomScroll.wCurZoomIndex = IMAGE_SIZE_FIRST - 1;
// Create the picture window controls
if( CreateViewerKids( hwndPicture, pPictureData ))
goto Failed; // Errors reported by function
pPictureData->spmsHScroll.wCurPos = 0;
pPictureData->spmsVScroll.wCurPos = 0;
// Set copy option default values
SetOptionsDefaults( hwndPicture, pPictureData );
if( pPictureData->qtoleOptions.bZoomHalf )
wZoomIndex = IMAGE_SIZE_50;
else if( pPictureData->qtoleOptions.bZoomDouble )
wZoomIndex = IMAGE_SIZE_200;
else
wZoomIndex = IMAGE_SIZE_100;
// Build picture. This initializes pPictureData->rcCurPictureRect.
if( ZoomPicture( hwndPicture, wZoomIndex ))
goto Failed; // Error displayed by function
// At this point, the picture is in a window whose size
// and position is the current MDI default . Now, resize to actual
// size of picture, without clipping if possible
// Get default corner
GetWindowRect( hwndPicture, &rcWindow );
MapWindowPoints( HWND_DESKTOP, ViewerQueryClientWindow(),
(LPPOINT) &rcWindow, 2 );
ptCorner = *((LPPOINT) &rcWindow.left);
// Adjust window to fit normal size of picture
rcWindow = pPictureData->rcCurPictureRect;
// get client rect from picture rect in client coordinates
ClientRectFromPicture( &rcWindow );
// Now adjust for windows stuff
AdjustWindowRect( &rcWindow,
GetWindowLong( hwndPicture, GWL_STYLE ), FALSE );
wWidth = rcWindow.right - rcWindow.left;
wHeight = rcWindow.bottom - rcWindow.top;
OffsetRect( &rcWindow, ptCorner.x - rcWindow.left,
ptCorner.y - rcWindow.top );
// rcWindow now contains the resized window positioned so that
// the UL corner is at the MDI default position
// Now see if it will fit on screen.
GetClientRect( ViewerQueryClientWindow(), &rcclientClient );
if( rcWindow.right > rcclientClient.right )
{ // extends beyond right border
// Try to shift it to the left
nDiff = rcclientClient.right - wWidth;
rcWindow.left = max( 0, nDiff );
rcWindow.right = rcclientClient.right;
}
if( rcWindow.bottom > rcclientClient.bottom )
{ // extends beyond bottom
// Try to shift it up
nDiff = rcclientClient.bottom - wHeight;
rcWindow.top = max( 0, nDiff );
rcWindow.bottom = rcclientClient.bottom;
}
MoveWindow( hwndPicture, rcWindow.left, rcWindow.top,
rcWindow.right - rcWindow.left,
rcWindow.bottom - rcWindow.top, TRUE );
SetCursor( hcursorSave );
SetFocus( hwndPicture );
// Tell qtole.dll that the picture wnd has been opened
if( ( lpOleData = ViewerQueryOleData()) && lpOleData->lpqtoleServer )
{qtoleOpenWnd.lStructSize = sizeof( qtoleOpenWnd );
qtoleOpenWnd.lVersion = VERSION_1;
qtoleOpenWnd.wObjectType = PICTURE_OBJECT;
qtoleOpenWnd.hwndObject = hwndPicture;
qtoleOpenWnd.lpObjectPath = pPictureData->szPicturePath;
qtoleOpenWnd.lpObjectName = pPictureData->szPictureName;
QTOLE_OpeningNewObjectWnd( lpOleData, &qtoleOpenWnd );
}
return 0L;
Failed:
if( hcursorSave )
SetCursor( hcursorSave );
if( pPictureData->phPicture != NULL)
DisposePicture( pPictureData->phPicture );
if( pPictureData->hpalPicture )
DeleteObject( pPictureData->hpalPicture );
SetWindowWord( hwndPicture, 0, 0 );
if( pPictureData )
LocalUnlock( hPictureData );
if( hPictureData )
LocalFree( hPictureData );
return -1;
}
// Function: CheckDupEnumProc - Checks for duplicate pictures and
// fixes up titles if there are any
// --------------------------------------------------------------------
// Parameters: As required by Microsoft Windows
//
// Returns: Always TRUE;
// --------------------------------------------------------------------
BOOL __export CALLBACK CheckDupEnumProc( HWND hwnd, LPARAM lParam )
// Look for duplicate pictures. Test is on path rather than just name
{char szBuffer[50]; // Temp buffer
HWND hwndActivePicture; // Handle of active picture wnd
NPPICTUREDATA pPictureData; // -> enum wnd picture data struct
NPPICTUREDATA pActivePictureData; // -> active wnd picture data struct
// skip active picture
if( ( hwndActivePicture = (HWND) LOWORD( lParam )) == hwnd )
return TRUE;
if( !GetClassName( hwnd, szBuffer, sizeof( szBuffer )) ||
lstrcmpi( szBuffer, VIEWER_PICTURE_CLASS ))
return TRUE;
pPictureData = (NPPICTUREDATA) GetWindowWord( hwnd, 0 );
pActivePictureData =
(NPPICTUREDATA) GetWindowWord( hwndActivePicture, 0 );
if( !pPictureData || !pActivePictureData )
return TRUE;
if( !lstrcmpi( pPictureData->szPicturePath,
pActivePictureData->szPicturePath ))
{ // Found a duplicate
g.wPictureCount++;
if( g.bCreating )
{if( pPictureData->wDuplicationIndex == 0 )
{pPictureData->wDuplicationIndex = 1;
wsprintf( szBuffer, "%s:%u",
(LPSTR) pPictureData->szPictureName,
pPictureData->wDuplicationIndex );
SetWindowText( hwnd, szBuffer );
}
}
else
{if( pPictureData->wDuplicationIndex >
pActivePictureData->wDuplicationIndex )
{pPictureData->wDuplicationIndex--;
wsprintf( szBuffer, "%s:%u",
(LPSTR) pPictureData->szPictureName,
pPictureData->wDuplicationIndex );
SetWindowText( hwnd, szBuffer );
}
if( pPictureData->wDuplicationIndex == 1 )
g.hwndFirstDup = hwnd;
}
if( pPictureData->hwndGetInfo &&
!PostMessage( pPictureData->hwndGetInfo,
WM_INFO_UPDATEFILENAME, 0, 0L ))
SendMessage( pPictureData->hwndGetInfo,
WM_INFO_UPDATEFILENAME, 0, 0L );
}
return TRUE;
}
// Function: ViewerEditCommands - Process WM_COMMAND, Edit popup messages
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture; Picture window
// WORD wIDItem; Menu id
// WORD wNotifyCode; notification message
//
// Returns: LONG generally 0L
// --------------------------------------------------------------------
static LONG NEAR ViewerEditCommands
(HWND hwndPicture, WPARAM wIDItem, WORD wNotifyCode )
{NPPICTUREDATA pPictureData; // -> picture data struct
HDC hdc; // Handle to device context
HDC hdcMem; // Handle to mem device context
RECT rcPicture; // Picture rect
HBITMAP hBitmap; // Handle to bitmap passed to clipboard
HBITMAP hSaveBitmap1; // Temp bitmap handle
HCURSOR hcursorSave; // Saved cursor
HBRUSH hbrushSave; // Prev brush
DIBHandle hbmpDIB; // Handle of DIB bitmap passed to clipboard
OSErr oserr; // Error return from DrawPictureFile
HPALETTE hpal; // Palette handle
LPQTOLE_OLEDATA lpOleData; // -> ole data
HPALETTE hpalSave; // Prev palette
if( !( pPictureData = (NPPICTUREDATA) GetWindowWord( hwndPicture, 0 )))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOPICDATA, VIEWER_STRING_CAPTION, MB_OK );
return 0L;
}
switch( wIDItem )
{case VIEWER_EDIT_COPYPICTURE:
if( IsIconic( hwndPicture ))
return 0L;
// If ole, let ole do the copy
if( ( lpOleData = ViewerQueryOleData()) && lpOleData->lpqtoleServer )
{PopulateOptionsStruct( hwndPicture, pPictureData );
QTOLE_Copy( lpOleData, (LPQTOLE_OPTIONS) &pPictureData->qtoleOptions );
// We must compensate for an error in certain drivers by
// resetting the palette back the way we found it
if( ViewerIsPalettized() &&
pPictureData->hpalPicture && ( hdc = GetDC( hwndPicture )))
{hpalSave = SelectPalette( hdc, pPictureData->hpalPicture, 0 );
RealizePalette( hdc );
SelectPalette( hdc, hpalSave, 0 );
ReleaseDC( hwndPicture, hdc );
}
}
else // No ole so do copy here
{if( !( hdc = GetDC( hwndPicture )))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NODC,
VIEWER_STRING_CAPTION, MB_OK );
return 0L;
}
rcPicture.left = rcPicture.top = 0;
rcPicture.right = pPictureData->idImageInfo.width;
rcPicture.bottom = pPictureData->idImageInfo.height;
if( !( hBitmap = CreateCompatibleBitmap
( hdc, rcPicture.right, rcPicture.bottom )))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_COPYFAILED,
VIEWER_STRING_CAPTION, MB_OK );
ReleaseDC( hwndPicture, hdc );
return 0L;
}
oserr = 1L; // initialize to nonzero value
if( (hdcMem = CreateCompatibleDC( hdc )) &&
( hSaveBitmap1 = SelectObject( hdcMem, hBitmap )))
{hcursorSave = SetCursor( LoadCursor( NULL, IDC_WAIT ));
hbrushSave = SelectObject( hdcMem, PICBACKGRNDBRUSH );
oserr = DrawPicture( hdcMem, pPictureData->phPicture,
&rcPicture, NULL );
SetCursor( hcursorSave );
// Unselect the bitmap and brush
SelectObject( hdcMem, hSaveBitmap1 );
if( hbrushSave )
SelectObject( hdcMem, hbrushSave );
if( !oserr )
{OpenClipboard( hwndPicture );
EmptyClipboard();
// Give bitmap to clipboard if OK
if( !SetClipboardData( CF_BITMAP, hBitmap ))
DeleteObject( hBitmap );
// Now add palette if there is one
if( ( hpal = GetPicturePalette( pPictureData->phPicture )) &&
!SetClipboardData( CF_PALETTE, hpal ))
DeleteObject( hpal );
// Now try to add DIBitmap to clipboard
if( ( hbmpDIB =
PictureToDIB( pPictureData->phPicture )) &&
!SetClipboardData( CF_DIB, hbmpDIB ))
GlobalFree( hbmpDIB );
CloseClipboard();
}
}
else
{if( hBitmap )
DeleteObject( hBitmap );
}
if( oserr )
CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_DRAWPICFAIL,
VIEWER_STRING_CAPTION, MB_OK );
if( hdcMem )
DeleteDC( hdcMem );
ReleaseDC( hwndPicture, hdc );
}
return 0L;
case VIEWER_EDIT_OPTIONS:
PopulateOptionsStruct( hwndPicture, pPictureData );
if( ViewerGetOptions( hwndPicture, &pPictureData->qtoleOptions ))
UpdatePictForOptions( hwndPicture, pPictureData, FALSE );
return 0L;
case VIEWER_EDIT_CANCELSEL:
if( !IsRectEmpty( &pPictureData->qtoleOptions.rcSelection ) &&
( hdc = GetDC( hwndPicture )))
{DrawSelectionRect( hwndPicture, hdc, pPictureData );
ReleaseDC( hwndPicture, hdc );
SetRectEmpty( &pPictureData->qtoleOptions.rcSelection );
}
return 0L;
}
return 0L; // should never get here
}
// Function: InitSelection - Initiates the selection
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Handle of picture wnd
// POINT ptCursor Cursor position
//
// Returns: BOOL TRUE if OK
// --------------------------------------------------------------------
static BOOL NEAR InitSelection( HWND hwndPicture, POINT ptCursor )
{NPPICTUREDATA pPictureData;
HDC hdc;
// First remove old selection
if( pPictureData = (NPPICTUREDATA) GetWindowWord( hwndPicture, 0 ))
{g.rcSelection = pPictureData->qtoleOptions.rcSelection;
if( !IsRectEmpty( &g.rcSelection ) &&
( hdc = GetDC( hwndPicture )))
{DrawSelectionRect( hwndPicture, hdc, pPictureData );
ReleaseDC( hwndPicture, hdc );
}
}
if( hdc = GetDC( NULL ))
{ClientToScreen( hwndPicture, &ptCursor );
*(LPPOINT) &g.rcSelection.left = ptCursor;
*(LPPOINT) &g.rcSelection.right = ptCursor;
DrawFocusRect( hdc, &g.rcSelection );
ReleaseDC( NULL, hdc );
return TRUE;
}
return FALSE;
}
// Function: MoveTheSelectRect - Move the selection rect
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Handle of picture wnd
// POINT ptCursor Cursor position
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR MoveTheSelectRect( HWND hwndPicture, POINT ptCursor )
{HDC hdc;
if( hdc = GetDC( NULL ))
{ClientToScreen( hwndPicture, &ptCursor );
DrawFocusRect( hdc, &g.rcSelection );
*(LPPOINT) &g.rcSelection.right = ptCursor;
if( g.rcSelection.right < g.rcSelection.left )
g.rcSelection.right = g.rcSelection.left;
if( g.rcSelection.bottom < g.rcSelection.top )
g.rcSelection.bottom = g.rcSelection.top;
DrawFocusRect( hdc, &g.rcSelection );
ReleaseDC( NULL, hdc );
}
return;
}
// Function: EndTheSelection - End the selection
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Handle of picture wnd
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR EndTheSelection( HWND hwndPicture )
{NPPICTUREDATA pPictureData;
int nZoomMult;
HDC hdc;
// Remove selection rect here and redraw later using function
// This is necessary because roundoff in convertions can cause
// one pixel differences in rect coordinates
if( hdc = GetDC( NULL ))
{DrawFocusRect( hdc, &g.rcSelection );
ReleaseDC( NULL, hdc );
}
if( pPictureData = (NPPICTUREDATA) GetWindowWord( hwndPicture, 0 ))
{if( !IsRectEmpty( &g.rcSelection ))
{MapWindowPoints( HWND_DESKTOP, hwndPicture,
(LPPOINT) &g.rcSelection, 2 );
ClientToPicture( (LPPOINT) &g.rcSelection, 2 );
// rcCurPictureRect knows about scroll offsets.
// These offsets are negative
OffsetRect( &g.rcSelection,
-pPictureData->rcCurPictureRect.left,
-pPictureData->rcCurPictureRect.top );
// Now convert to 100% zoom. rcSelection will be stored
// at 100% zoom. Copy will reflect actual zoom
nZoomMult = (int) ViewerQueryZoomMultiplier
( pPictureData->zsZoomScroll.wCurZoomIndex );
g.rcSelection.left = MulDiv( g.rcSelection.left, 100, nZoomMult );
g.rcSelection.top = MulDiv( g.rcSelection.top, 100, nZoomMult );
g.rcSelection.right = MulDiv( g.rcSelection.right, 100, nZoomMult );
g.rcSelection.bottom = MulDiv( g.rcSelection.bottom, 100, nZoomMult );
// Now check that section is inside picture
if( g.rcSelection.left < 0 )
g.rcSelection.left = 0;
if( g.rcSelection.top < 0 )
g.rcSelection.top = 0;
if( g.rcSelection.right > (int) pPictureData->idImageInfo.width )
g.rcSelection.right = pPictureData->idImageInfo.width;
if( g.rcSelection.bottom > (int) pPictureData->idImageInfo.height )
g.rcSelection.bottom = pPictureData->idImageInfo.height;
// g.rcSelection now has selection relative to UL corner
// of picture at 100% zoom
}
pPictureData->qtoleOptions.rcSelection = g.rcSelection;
// Now redraw the rect to leave it visible
if( hdc = GetDC( hwndPicture ))
{DrawSelectionRect( hwndPicture, hdc, pPictureData );
ReleaseDC( hwndPicture, hdc );
}
}
return;
}
// Function: ViewerImageCommands - Process WM_COMMAND, Image popup messages
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture; Picture window
// WORD wIDItem; Menu id
// WORD wNotifyCode; notification message
//
// Returns: LONG generally 0L
// --------------------------------------------------------------------
static LONG NEAR ViewerImageCommands
(HWND hwndPicture, WPARAM wIDItem, WORD wNotifyCode )
{DLGPROC lpDlgProc; // -> dlg callback proc
HWND hInfoDialog; // Handle to modeless info dialog
NPPICTUREDATA pPictureData; // -> picture data struct
if( !(pPictureData =
(NPPICTUREDATA) GetWindowWord( hwndPicture, 0 )))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOPICDATA, VIEWER_STRING_CAPTION, MB_OK );
return 0L;
}
switch( wIDItem )
{case VIEWER_IMAGE_GETINFO:
if( pPictureData->hwndGetInfo )
{SetFocus( pPictureData->hwndGetInfo );
}
else if( !(lpDlgProc = (DLGPROC) MakeProcInstance
( (FARPROC) GetInfoDlgProc, ViewerQueryInstance())) ||
!( hInfoDialog = CreateDialog( ViewerQueryResources(),
MAKEINTRESOURCE( VIEWER_DLG_GETINFO ),
ViewerQueryFrameWindow(), lpDlgProc )))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOMEMORY, NULL, MB_OK );
}
return 0L;
case VIEWER_IMAGE_HALFSIZE:
case VIEWER_IMAGE_NORMALSIZE:
case VIEWER_IMAGE_DOUBLESIZE:
// errors reported by function
ZoomPicture( hwndPicture, wIDItem );
return 0L;
}
return 0L; // should never get here
}
// Function: PaintThePicture - processes the WM_PAINT message when normal
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Handle of Picture window
//
// Returns: LONG 0L if successful
// --------------------------------------------------------------------
static LONG NEAR PaintThePicture( HWND hwndPicture )
{PAINTSTRUCT ps; // Paint struct
NPPICTUREDATA pPictureData; // -> picture data struct
HCURSOR hcursorSave; // Save cursor handle
HBRUSH hbrushSave; // Prev brush
RECT rcclientPicture; // Picture rect in client coordinates
int nRegion; // Return from IntersectClipRegion
OSErr oserr; // DrawPicture error return
WORD wIDError; // Error message ID
if( !( pPictureData =
(NPPICTUREDATA) GetWindowWord( hwndPicture, 0 )))
{if( BeginPaint( hwndPicture, &ps ))
EndPaint( hwndPicture, &ps );
return 0L;
}
// Always paint the grow box. This must come before BeginPaint
InvalidateRect( hwndPicture, &pPictureData->rcGrowBox, FALSE );
if( !BeginPaint( hwndPicture, &ps ))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOMEMORY,
VIEWER_STRING_CAPTION, MB_OK );
return VIEWER_STRING_NOMEMORY;
}
// First draw the grow box and exclude the rect so that picture isn't
// draw over it below
PaintTheGrowBox( hwndPicture, ps.hdc, pPictureData );
ExcludeClipRect( ps.hdc, pPictureData->rcGrowBox.left,
pPictureData->rcGrowBox.top,
pPictureData->rcGrowBox.right,
pPictureData->rcGrowBox.bottom );
// Note: rcCurPictureRect knows about scrolling offset. left and
// top are negative if pict is scrolled. (0,0) is always the UL
// corner of the displayed portion of the picture in picture
// coordinates.
rcclientPicture = pPictureData->rcCurPictureRect;
// Convert to client coordinates since ps.hdc understands client
// coordinates
PictureToClient( (LPPOINT) &rcclientPicture, 2 );
// Paint the background
hbrushSave = SelectObject( ps.hdc, PICBACKGRNDBRUSH );
SaveDC( ps.hdc );
ExcludeClipRect( ps.hdc, rcclientPicture.left, rcclientPicture.top,
rcclientPicture.right, rcclientPicture.bottom );
FillRect( ps.hdc, &ps.rcPaint, PICBACKGRNDBRUSH );
RestoreDC( ps.hdc, -1 );
if( hbrushSave )
SelectObject( ps.hdc, hbrushSave );
// Check if picture needs to be painted
SaveDC( ps.hdc );
nRegion = IntersectClipRect( ps.hdc,
rcclientPicture.left, rcclientPicture.top,
rcclientPicture.right, rcclientPicture.bottom );
if( ( nRegion == ERROR ) || ( nRegion == NULLREGION ))
{RestoreDC( ps.hdc, -1 );
EndPaint( hwndPicture, &ps );
return 0L;
}
// Draw picture
hcursorSave = SetCursor( LoadCursor( NULL, IDC_WAIT ));
if( oserr = DrawPicture( ps.hdc, pPictureData->phPicture,
&rcclientPicture, NULL ))
{if( oserr == insufficientMemory )
wIDError = VIEWER_STRING_NOMEMORY;
else
wIDError = VIEWER_STRING_DRAWPICFAIL;
CommonTellUser( ViewerQueryResources(), wIDError,
VIEWER_STRING_CAPTION, MB_OK );
// Validate rect to prevent infinite loop
ValidateRect( hwndPicture, NULL );
SetCursor( hcursorSave );
RestoreDC( ps.hdc, -1 );
EndPaint( hwndPicture, &ps );
return VIEWER_STRING_DRAWPICFAIL;
}
RestoreDC( ps.hdc, -1 );
if( !IsRectEmpty( &pPictureData->qtoleOptions.rcSelection ))
DrawSelectionRect( hwndPicture, ps.hdc, pPictureData );
SetCursor( hcursorSave );
// Done painting
EndPaint( hwndPicture, &ps );
return 0L;
}
// Function: DrawSelectionRect - Draws the selection rect
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture HWND of picture wnd
// HDC hdc HDC of picture wnd
// NPPICTUREDATA pPictureData
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR DrawSelectionRect
( HWND hwndPicture, HDC hdc, NPPICTUREDATA pPictureData )
{RECT rcSelection;
RECT rcPicture;
int nZoomMult;
int nRegion;
// Get picture rect and prevent drawing outside the picture
GetClientRect( hwndPicture, &rcPicture );
PictureRectFromClient( &rcPicture );
nRegion = IntersectClipRect( hdc,
rcPicture.left, rcPicture.top,
rcPicture.right, rcPicture.bottom );
if( ( nRegion == ERROR ) || ( nRegion == NULLREGION ))
return;
// Convert to current zoom
rcSelection = pPictureData->qtoleOptions.rcSelection;
nZoomMult = (int) ViewerQueryZoomMultiplier
( pPictureData->zsZoomScroll.wCurZoomIndex );
rcSelection.left = MulDiv( rcSelection.left, nZoomMult, 100 );
rcSelection.top = MulDiv( rcSelection.top, nZoomMult, 100 );
rcSelection.right = MulDiv( rcSelection.right, nZoomMult, 100 );
rcSelection.bottom = MulDiv( rcSelection.bottom, nZoomMult, 100 );
// Offset for current scroll and convert to client coordinates
OffsetRect( &rcSelection,
pPictureData->rcCurPictureRect.left,
pPictureData->rcCurPictureRect.top );
PictureToClient( (LPPOINT) &rcSelection, 2 );
DrawFocusRect( hdc, &rcSelection );
return;
}
// Function: PaintTheIcon - processes the WM_PAINT message when iconic
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Handle of Picture window
//
// Returns: LONG 0L
// --------------------------------------------------------------------
static LONG NEAR PaintTheIcon( HWND hwndPicture )
{PAINTSTRUCT ps; // Paint struct
NPPICTUREDATA pPictureData; // -> picture data struct
HDC hmemDC; // Memory DC
HBITMAP hbitmapSave; // Prev bitmap
BITMAP bm; // Bitmap struct
LPBITMAPINFOHEADER lpbmih; // -> bitmapinfo header struct
HPALETTE hpalSave; // Prev palette
HBRUSH hbrush; // Background brush
static RECT rcPic =
{4, 4, 32, 32}; // Rect used in painting pic
InvalidateRect( hwndPicture, NULL, FALSE );
if( !BeginPaint( hwndPicture, &ps ))
return 0L;
if( !( pPictureData = (NPPICTUREDATA)
GetWindowWord( hwndPicture, 0 )) ||
( !pPictureData->lpDIBIconMem && !pPictureData->hbitmapIcon ))
{if( hbrush = CreateSolidBrush( GetSysColor( COLOR_APPWORKSPACE )))
{FillRect( ps.hdc, &ps.rcPaint, hbrush );
DeleteObject( hbrush );
}
if( g.hpictIcon )
DrawIcon( ps.hdc, 2, 2, g.hpictIcon );
EndPaint( hwndPicture, &ps );
return 0L;
}
// Will have DIB icon only if palettized
if( pPictureData->lpDIBIconMem )
{lpbmih = (LPBITMAPINFOHEADER) pPictureData->lpDIBIconMem;
// Select the current system palette into the dc so SetDIBits..
// can do color matching. The system palette is set by the last
// call to RealizePalette and so the current palette will
// match the picture's palette only if the picture is active
hpalSave = SelectPalette( ps.hdc, g.hpalCurrentSystem, FALSE );
SetDIBitsToDevice( ps.hdc, rcPic.left, rcPic.top,
(WORD) lpbmih->biWidth, (WORD) lpbmih->biHeight,
0, 0, 0, (WORD) lpbmih->biHeight,
(LPVOID) ((LPSTR) lpbmih +
(WORD) lpbmih->biSize + SIZE_COLOR_TABLE ),
pPictureData->lpDIBIconMem, DIB_RGB_COLORS );
if( hpalSave )
SelectPalette( ps.hdc, hpalSave, FALSE );
// Now paint the background
SaveDC( ps.hdc );
ExcludeClipRect( ps.hdc, rcPic.left, rcPic.top,
rcPic.right, rcPic.bottom );
// COLOR_APPWORKSPACE is standard MDI background color
if( hbrush = CreateSolidBrush( GetSysColor( COLOR_APPWORKSPACE )))
{FillRect( ps.hdc, &ps.rcPaint, hbrush );
DeleteObject( hbrush );
}
RestoreDC( ps.hdc, -1 );
// Now draw the picture frame
if( g.hpictIcon )
DrawIcon( ps.hdc, 2, 2, g.hpictIcon );
}
else
{hmemDC = NULL;
if( pPictureData->hbitmapIcon &&
( hmemDC = CreateCompatibleDC( ps.hdc )) &&
( hbitmapSave =
SelectObject( hmemDC, pPictureData->hbitmapIcon )))
{GetObject( pPictureData->hbitmapIcon, sizeof( BITMAP ), &bm );
BitBlt( ps.hdc, 0, 0, bm.bmWidth, bm.bmHeight,
hmemDC, 0, 0, SRCCOPY );
SelectObject( hmemDC, hbitmapSave );
}
else
{if( hbrush = CreateSolidBrush( GetSysColor( COLOR_APPWORKSPACE )))
{FillRect( ps.hdc, &ps.rcPaint, hbrush );
DeleteObject( hbrush );
}
if( g.hpictIcon )
DrawIcon( ps.hdc, 2, 2, g.hpictIcon );
}
if( hmemDC )
DeleteDC( hmemDC );
}
EndPaint( hwndPicture, &ps );
return 0L;
}
// Function: BuildIconBitmap - builds the icon bitmap
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Handle of picture wnd
// NPPICTUREDATA pPictureData -> picture data struct
//
// Returns: LONG 0L
// --------------------------------------------------------------------
static BOOL NEAR BuildIconBitmap
( HWND hwndPicture, NPPICTUREDATA pPictureData )
{HDC hdc; // DC of picture
HDC hmemDC; // Memory dc
HBRUSH hbrush; // Temp background brush
HBRUSH hbrushSave; // Prev brush
HBITMAP hbitmapSave; // Prev bitmap
HBITMAP hbitmap; // Handle of icon bitmap
HGLOBAL hbmi; // Memory handle for DIB info struct
HGLOBAL hnewbmi; // Temp memory handle
BITMAPINFOHEADER bi; // Bitmap info header struct
LPVOID lpbmi; // -> bitmap info struct
BITMAP bm; // BITMAP struct
HPALETTE hpalSave; // Prev palette
HCURSOR hcursorSave; // Prev cursor
RECT rcPicRect; // Picture rect
WORD wIconBmpWidth; // Icon width
WORD wIconBmpHeight; // Icon height
WORD wProportional; // Temp
static RECT rcIcon =
{2, 2, 34, 34}; // Rect used in painting icon
static RECT rcPicbmp =
{4, 4, 32, 32}; // Rect used in painting pic
static RECT rcPicdib =
{0, 0, 28, 28}; // Rect used in painting pic
static RECT rcBitmap = // Overall bitmap dimensions
{0, 0, 36, 36 };
// Macro used to align on ULONG boundary
// From 3.1 SDK sample code, dib.h
#define WIDTHBYTES(i) ( ( i + 31 ) / 32 * 4 )
pPictureData->hbitmapIcon = NULL;
pPictureData->lpDIBIconMem = NULL;
if( !( hdc = GetDC( hwndPicture )))
{return FALSE;
}
if( !( hmemDC = CreateCompatibleDC( hdc )))
{ReleaseDC( hwndPicture, hdc );
return FALSE;
}
hbitmap = NULL;
hpalSave = NULL;
hcursorSave = SetCursor( LoadCursor( NULL, IDC_WAIT ));
// Get picture rect with proportions of the original pic
rcPicRect = rcPicbmp;
wIconBmpWidth = rcPicbmp.right - rcPicbmp.left;
wIconBmpHeight = rcPicbmp.bottom - rcPicbmp.top;
if( pPictureData->idImageInfo.width >
pPictureData->idImageInfo.height )
{wProportional = MulDiv( wIconBmpHeight,
pPictureData->idImageInfo.width,
pPictureData->idImageInfo.height );
rcPicRect.left -= ( wProportional - wIconBmpWidth ) / 2;
rcPicRect.right = rcPicRect.left + wProportional;
}
else if( pPictureData->idImageInfo.width <
pPictureData->idImageInfo.height )
{wProportional = MulDiv( wIconBmpWidth,
pPictureData->idImageInfo.height,
pPictureData->idImageInfo.width );
rcPicRect.top -= ( wProportional - wIconBmpHeight ) / 2;
rcPicRect.bottom = rcPicRect.top + wProportional;
}
if( ( hbitmap = CreateCompatibleBitmap( hdc,
rcBitmap.right, rcBitmap.bottom )) &&
( hbitmapSave = SelectObject( hmemDC, hbitmap )))
{ //First fill the background
if( hbrush = CreateSolidBrush( GetSysColor( COLOR_APPWORKSPACE )))
{FillRect( hmemDC, &rcBitmap, hbrush );
DeleteObject( hbrush );
}
// Now draw the picture.
// Keep picture inside the allowed rect
SaveDC( hmemDC );
IntersectClipRect( hmemDC, rcPicbmp.left, rcPicbmp.top,
rcPicbmp.right, rcPicbmp.bottom );
hbrushSave = SelectObject( hmemDC, PICBACKGRNDBRUSH );
if( DrawPicture( hmemDC, pPictureData->phPicture, &rcPicRect, NULL ))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_DRAWPICFAIL,
VIEWER_STRING_CAPTION, MB_OK );
}
SelectObject( hmemDC, hbrushSave );
RestoreDC( hmemDC, -1 );
// Now draw the picture frame
if( g.hpictIcon )
DrawIcon( hmemDC, 2, 2, g.hpictIcon );
SelectObject( hmemDC, hbitmapSave );
pPictureData->hbitmapIcon = hbitmap;
hbitmap = NULL;
}
else
{goto IconFailed;
}
if( ViewerIsPalettized()) // Palettized, use DIB bitmap, but only for picture
{ // Should always be a palette but test anyway
if( pPictureData->hpalPicture &&
!( hpalSave = SelectPalette
( hdc, pPictureData->hpalPicture, FALSE )))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_SELPALFAILED, NULL, MB_OK );
goto IconFailed;
}
// Need to offset rcPicRect because of differences btwn
// the origins of rcPicbmp and rcPicdib; ( 4, 4) vs ( 0, 0)
OffsetRect( &rcPicRect, -rcPicbmp.left, -rcPicbmp.top );
if( ( hbitmap = CreateCompatibleBitmap( hdc,
rcPicdib.right, rcPicdib.bottom )) &&
( hbitmapSave = SelectObject( hmemDC, hbitmap )))
{hbrushSave = SelectObject( hmemDC, PICBACKGRNDBRUSH );
if( DrawPicture( hmemDC, pPictureData->phPicture,
&rcPicRect, NULL ))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_DRAWPICFAIL,
VIEWER_STRING_CAPTION, MB_OK );
SelectObject( hmemDC, hbitmapSave );
SelectObject( hmemDC, hbrushSave );
goto IconFailed;
}
SelectObject( hmemDC, hbrushSave );
SelectObject( hmemDC, hbitmapSave );
}
else
{goto IconFailed;
}
// Now convert to DIB bitmap
// Initialize bitmap info header struct
GetObject( hbitmap, sizeof( BITMAP ), &bm );
bi.biSize = sizeof( BITMAPINFOHEADER );
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
if( !( hbmi = GlobalAlloc( GHND, bi.biSize + SIZE_COLOR_TABLE )))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOMEMORY, NULL, MB_OK );
goto IconFailed;
}
lpbmi = (LPVOID) GlobalLock( hbmi );
// First get bitmap size by using NULL argument
*(LPBITMAPINFOHEADER) lpbmi = bi;
GetDIBits( hdc, hbitmap, 0, bm.bmHeight, NULL,
(LPBITMAPINFO) lpbmi, DIB_RGB_COLORS );
bi = *(LPBITMAPINFOHEADER) lpbmi;
// If driver failed to set size, make a guess
if( bi.biSizeImage == 0 )
bi.biSizeImage = bi.biHeight *
WIDTHBYTES( (DWORD) bm.bmWidth * bi.biBitCount );
// Now realloc to get space for bitmap bits
GlobalUnlock( hbmi );
if( !( hnewbmi = GlobalReAlloc( hbmi,
bi.biSize + SIZE_COLOR_TABLE + bi.biSizeImage, GHND )))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOMEMORY, NULL, MB_OK );
GlobalFree( hbmi );
goto IconFailed;
}
hbmi = hnewbmi;
lpbmi = (LPVOID) GlobalLock( hbmi );
// Now get bitmap bits
if( bm.bmHeight != GetDIBits( hdc, hbitmap, 0, bm.bmHeight,
(LPVOID)((LPSTR) lpbmi + (WORD) bi.biSize + SIZE_COLOR_TABLE ),
(LPBITMAPINFO) lpbmi, DIB_RGB_COLORS ))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOMAKEDIB, NULL, MB_OK );
GlobalUnlock( hbmi );
GlobalFree( hbmi );
goto IconFailed;
}
// Done. Save -> to DIB and toss device dependent bitmap
pPictureData->lpDIBIconMem = (LPBITMAPINFO) lpbmi;
DeleteObject( pPictureData->hbitmapIcon );
pPictureData->hbitmapIcon = NULL;
DeleteObject( hbitmap );
SelectPalette( hdc, hpalSave, FALSE );
}
SetCursor( hcursorSave );
ReleaseDC( hwndPicture, hdc );
DeleteDC ( hmemDC );
return TRUE;
IconFailed:
if( hcursorSave )
SetCursor( hcursorSave );
if( hpalSave )
SelectPalette( hdc, hpalSave, FALSE );
if( hbitmap )
DeleteObject( hbitmap );
DeleteDC( hmemDC );
ReleaseDC( hwndPicture, hdc );
return FALSE;
}
// Function: StoreCurrentSystemPalette - stores the current system palette just
// before calling RealizePalette.
// This is also called during frame
// wnd WM_PALETTECHANGED processing
// --------------------------------------------------------------------
// Parameters: HPALETTE hpalPicture Palette of picture that realized
// palette, otherwise NULL
//
// Returns: VOID
// --------------------------------------------------------------------
VOID FAR StoreCurrentSystemPalette( HPALETTE hpalPicture )
{if( hpalPicture )
g.hpalCurrentSystem = hpalPicture;
return;
}
// Function: KeyDownMessage - processes the WM_KEYDOWN message
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Handle of picture window
// WPARAM wParam WM_KEYDOWN wParam
// LPARAM lParam WM_KEYDOWN lParam
//
// Returns: LONG Generally 0L
// --------------------------------------------------------------------
static LONG NEAR KeyDownMessage
( HWND hwndPicture, WPARAM wParam, LPARAM lParam )
// Process keyboard interface messages
{NPPICTUREDATA pPictureData; // -> picture data struct
WORD wScroll; // Scrolling parameter
switch( wParam )
{case VK_LEFT:
case VK_RIGHT:
if( ISKEYDOWN( VK_CONTROL ))
wScroll = ( wParam == VK_LEFT ) ? SB_PAGELEFT: SB_PAGERIGHT;
else
wScroll = ( wParam == VK_LEFT ) ? SB_LINELEFT: SB_LINERIGHT;
return ProcessHorzScroll( hwndPicture, wScroll, 0 );
case VK_UP:
case VK_DOWN:
if( ISKEYDOWN( VK_CONTROL ))
wScroll = ( wParam == VK_UP ) ? SB_PAGEUP: SB_PAGEDOWN;
else
wScroll = ( wParam == VK_UP ) ? SB_LINEUP: SB_LINEDOWN;
return ProcessVertScroll( hwndPicture, wScroll, 0 );
case VK_PRIOR:
case VK_NEXT:
if( ISKEYDOWN( VK_CONTROL ))
return ProcessHorzScroll( hwndPicture,
( wParam == VK_PRIOR ? SB_PAGELEFT: SB_PAGERIGHT ), 0 );
else
return ProcessVertScroll( hwndPicture,
( wParam == VK_PRIOR ? SB_PAGEUP: SB_PAGEDOWN ), 0 );
case VK_HOME:
case VK_END:
return ScrollToCorner( hwndPicture, wParam );
case VK_ADD:
case VK_SUBTRACT:
if( (pPictureData = (NPPICTUREDATA)
GetWindowWord( hwndPicture, 0 )) &&
pPictureData->zsZoomScroll.hwnd )
return SendMessage( pPictureData->zsZoomScroll.hwnd,
WM_KEYDOWN, wParam, lParam );
break;
}
return 0L;
}
// Function: PrintPicture - prints indicated number of copies of
// the picture
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Handle of Picture window
// LPPRINTDLG lppd -> to PRINTDLG struct created
// by print common dialog
//
// Returns: LONG 0L if successful
// --------------------------------------------------------------------
static LONG NEAR PrintPicture( HWND hwndPicture, LPPRINTDLG lppd )
{NPPICTUREDATA pPictureData; // -> picture data struct
WORD i; // Counter
DOCINFO diDocInfo; // Document info struct
BOOL bError; // Error flag
RECT rcPicture; // Picture rect
int nError; // Error return
int xRes; // Horz printer resolution
int yRes; // Vert printer resolution
int xOffset; // Horz offset to center picture
int yOffset; // Vert offset to center picture
OSErr oserr; // Error return from DrawPictureFile
WORD wWidthPage; // Width of printed page in pixels
WORD wHeightPage; // Height of printed page in pixels
if( !(pPictureData =
(NPPICTUREDATA) GetWindowWord( hwndPicture, 0 )))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOPICDATA, NULL, MB_OK );
// Turn off not reported flag
return SP_ERROR & ~SP_NOTREPORTED;
}
diDocInfo.cbSize = sizeof( DOCINFO );
diDocInfo.lpszDocName = pPictureData->szPictureName;
diDocInfo.lpszOutput = (LPSTR) NULL;
bError = FALSE;
oserr = 0L;
nError = SP_ERROR;
wWidthPage = GetDeviceCaps( lppd->hDC, HORZRES );
wHeightPage = GetDeviceCaps( lppd->hDC, VERTRES );
// get resolution of printer
xRes = MulDiv( wWidthPage, 254,
GetDeviceCaps( lppd->hDC, HORZSIZE ) * 10 );
yRes = MulDiv( wHeightPage, 254,
GetDeviceCaps( lppd->hDC, VERTSIZE ) * 10 );
// Scale picture rect for differences in resolution
rcPicture.right = MulDiv( pPictureData->idImageInfo.width,
xRes, HIWORD( pPictureData->idImageInfo.hRes ));
rcPicture.bottom = MulDiv( pPictureData->idImageInfo.height,
yRes, HIWORD( pPictureData->idImageInfo.vRes ));
rcPicture.left = rcPicture.top = 0;
// Now make sure that picture fits on page
if( rcPicture.right > (int) wWidthPage )
{rcPicture.bottom = MulDiv( rcPicture.bottom,
wWidthPage, rcPicture.right );
rcPicture.right = wWidthPage;
}
if( rcPicture.bottom > (int) wHeightPage )
{rcPicture.right = MulDiv( rcPicture.right,
wHeightPage, rcPicture.bottom );
rcPicture.bottom = wHeightPage;
}
// Now center rect on page
xOffset = ( wWidthPage - rcPicture.right ) / 2;
yOffset = ( wHeightPage - rcPicture.bottom ) / 2;
OffsetRect( &rcPicture, xOffset, yOffset );
// Start printing. Loop over number of copies
if( StartDoc( lppd->hDC, &diDocInfo ) > 0 )
{for( i=0; (i < lppd->nCopies) && !bError; i++)
{if( StartPage( lppd->hDC ) > 0 )
{if( (oserr = DrawPicture( lppd->hDC,
pPictureData->phPicture, &rcPicture, NULL )) != 0L )
{ // DrawPicture failed, abort the print
AbortDoc( lppd->hDC );
bError = TRUE;
}
else
{if( ( nError = EndPage( lppd->hDC )) < 0 )
bError = TRUE;
}
}
else
bError = TRUE;
}
}
else
bError = TRUE;
if( !bError )
EndDoc( lppd->hDC );
else if( oserr )
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_DRAWPICFAIL,
VIEWER_STRING_PRT_CAPTION, MB_OK );
// Error has been reported, turn off "not reported" bit
nError = SP_ERROR & ~SP_NOTREPORTED;
}
return (LONG) nError;
}
// Function: GetInfoDlgProc - Get Info dialog proc
// --------------------------------------------------------------------
// Parameters: As required by Microsoft Windows
//
// Returns: As required by Microsoft Windows
// --------------------------------------------------------------------
BOOL __export CALLBACK GetInfoDlgProc
( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam )
{NPPICTUREDATA pPictureData; // -> picture data struct
HWND hwndPicture; // Handle to picture window
HWND hwndCtl; // Handle of control
HDC hdc; // DC of control
int nHeight; // Text height
switch( msg )
{case WM_INITDIALOG:
hwndPicture = (HWND) SendMessage
( ViewerQueryClientWindow(), WM_MDIGETACTIVE, 0, 0L );
// Use property to associate picture window handle with
// info dialog. This is necessary because MDI makes frame
// window the parent of all dialogs no matter what handle
// is used in the CreateDialog call
SetProp( hdlg, GETINFOPICTUREPROP, (HANDLE) hwndPicture );
if( pPictureData = (NPPICTUREDATA)
GetWindowWord( hwndPicture, 0 ))
{pPictureData->hwndGetInfo = hdlg;
if( hdc = GetDC( hdlg ))
{nHeight = -MulDiv( 8, GetDeviceCaps( hdc, LOGPIXELSY ), 72 );
if( pPictureData->hfInfo = MakeAnArialFont( hdc, nHeight ))
{hwndCtl = GetWindow( hdlg, GW_CHILD );
while( hwndCtl )
{if( GetDlgCtrlID( hwndCtl ) != IDOK )
SendMessage( hwndCtl, WM_SETFONT,
(WPARAM) pPictureData->hfInfo, 0 );
hwndCtl = GetWindow( hwndCtl, GW_HWNDNEXT );
}
}
ReleaseDC( hdlg, hdc );
}
FillPictureInfo( hdlg, pPictureData );
}
return TRUE;
case WM_ACTIVATE:
ViewerSetActiveModeless( wParam, hdlg );
return TRUE;
case WM_COMMAND:
return DestroyWindow( hdlg );
// WM_USER messages
case WM_INFO_UPDATEFILENAME:
hwndPicture = (HWND) GetProp( hdlg, GETINFOPICTUREPROP );
if( pPictureData = (NPPICTUREDATA)
GetWindowWord( hwndPicture, 0 ))
UpdateInfoFileName( hdlg, pPictureData );
break;
case WM_INFO_CURRENTSIZE:
hwndPicture = (HWND) GetProp( hdlg, GETINFOPICTUREPROP );
if( pPictureData = (NPPICTUREDATA)
GetWindowWord( hwndPicture, 0 ))
UpdateInfoCurrentSize( hdlg, pPictureData );
break;
// end WM_USER messages
case WM_DESTROY:
hwndPicture = (HWND) GetProp( hdlg, GETINFOPICTUREPROP );
if( IsWindow( hwndPicture ) && ( pPictureData =
(NPPICTUREDATA) GetWindowWord( hwndPicture, 0 )))
{pPictureData->hwndGetInfo = NULL;
if( pPictureData->hfInfo )
DeleteObject( pPictureData->hfInfo );
pPictureData->hfInfo = NULL;
}
RemoveProp( hdlg, GETINFOPICTUREPROP );
return FALSE;
}
return FALSE;
}
// Function: FillPictureInfo - Fills dialog controls with picture data
// --------------------- -----------------------------------------------
// Parameters: HWND hdlg Handle of dialog wnd
// NPPICTUREDATA pPictureData -> to PICTUREDATA struct
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR FillPictureInfo( HWND hdlg, NPPICTUREDATA pPictureData )
{char szBuffer[50]; // buffer
char szFormat[20]; // Format buffer
WORD wNormalWidth; // Normal width of picture
WORD wNormalHeight; // Normal height of picture
DWORD dwColors; // Number of colors
DWORD dwSize; // Uncompressed size
WORD wIDString; // Resource string id
// Picture name: Append duplication index if > 0
UpdateInfoFileName( hdlg, pPictureData );
// Filesize
SetDlgItemText( hdlg, IMAGE_INFO_FILESIZE,
(LPSTR) pPictureData->szFileSizeOnDisk );
// Current Width and Height
UpdateInfoCurrentSize( hdlg, pPictureData );
// Normal Width and Height
wNormalWidth = pPictureData->idImageInfo.width;
wNormalHeight = pPictureData->idImageInfo.height;
LoadString( ViewerQueryResources(), VIEWER_STRING_WANDH,
szFormat, sizeof( szFormat ));
wsprintf( szBuffer, szFormat, wNormalWidth, wNormalHeight );
SetDlgItemText( hdlg, IMAGE_INFO_WANDH, szBuffer );
// Resolution
if( ((LONG) pPictureData->idImageInfo.hRes == -1L ) ||
((LONG) pPictureData->idImageInfo.hRes == 0L ))
LoadString( ViewerQueryResources(),
VIEWER_STRING_NORESOLUTION, szBuffer, sizeof( szBuffer ));
else
{LoadString( ViewerQueryResources(),
VIEWER_STRING_RESOLUTION, szFormat, sizeof( szFormat ));
wsprintf( szBuffer, szFormat,
HIWORD( pPictureData->idImageInfo.hRes ));
}
SetDlgItemText( hdlg, IMAGE_INFO_RESOLUTION, szBuffer );
// Normal colors
switch( pPictureData->idImageInfo.depth )
{case 1: // Black and White
wIDString = VIEWER_STRING_CLRS_BANDW; break;
case 1 + 32: // 2 Grays
wIDString = VIEWER_STRING_CLRS_2GRAYS; break;
case 2: // 4 Colors
wIDString = VIEWER_STRING_CLRS_4COLORS; break;
case 2 + 32: // 4 Grays
wIDString = VIEWER_STRING_CLRS_4GRAYS; break;
case 4: // 16 Colors
wIDString = VIEWER_STRING_CLRS_16COLORS; break;
case 4 + 32: // 16 Grays
wIDString = VIEWER_STRING_CLRS_16GRAYS; break;
case 8: // 256 Colors
wIDString = VIEWER_STRING_CLRS_256COLORS; break;
case 8 + 32: // 256 Grays
wIDString = VIEWER_STRING_CLRS_256GRAYS; break;
case 16: // Thousands of Colors
wIDString = VIEWER_STRING_CLRS_THOUSANDS; break;
case 24: // Millions of Colors
wIDString = VIEWER_STRING_CLRS_MILLIONS; break;
case 32: // Millions of Colors+
wIDString = VIEWER_STRING_CLRS_MILLNSPLUS; break;
default:
wIDString = 0xffff;
if( pPictureData->idImageInfo.depth < 32 )
{LoadString( ViewerQueryResources(),
VIEWER_STRING_COLORS, szFormat, sizeof( szFormat ));
dwColors = 1L << pPictureData->idImageInfo.depth;
wsprintf( szBuffer, szFormat, dwColors );
}
else
{szBuffer[0] = '\0';
}
break;
}
if( wIDString != 0xffff )
LoadString( ViewerQueryResources(),
wIDString, szBuffer, sizeof( szBuffer ));
SetDlgItemText( hdlg, IMAGE_INFO_COLORS, szBuffer );
// Compressor. Compressor type displayed is the string stored for use in
// the banner bar rather that the DWORD value such as 'jpeg'
SetDlgItemText( hdlg, IMAGE_INFO_COMPRESSOR,
pPictureData->szPictType );
// Quality
if( pPictureData->idImageInfo.CodecType )
{*((PDWORD) &szBuffer) = pPictureData->idImageInfo.CodecType;
szBuffer[ sizeof(DWORD) ] = '\0';
}
if( !pPictureData->idImageInfo.CodecType ||
!lstrcmpi( szBuffer, "raw " ))
{szBuffer[0] = '\0';
}
else
{LoadString( ViewerQueryResources(),
VIEWER_STRING_QUALITY, szBuffer, sizeof( szBuffer ));
}
SetDlgItemText( hdlg, IMAGE_INFO_QUALITY, szBuffer );
// Uncompressed size
dwSize = ( (DWORD) wNormalWidth * wNormalHeight *
pPictureData->idImageInfo.depth ) / 8L;
if( dwSize < 1000L )
{wIDString = VIEWER_STRING_SIZEBYTES;
}
else
{dwSize /= 1000L;
wIDString = VIEWER_STRING_SIZEKBYTES;
}
LoadString( ViewerQueryResources(), wIDString,
szFormat, sizeof( szFormat ));
wsprintf( szBuffer, szFormat, dwSize );
SetDlgItemText( hdlg, IMAGE_INFO_UNCOMPSIZE, szBuffer );
return;
}
// Function: UpdateInfoFileName - Updates the file name with the current
// instance count in the info dialog
// --------------------- -----------------------------------------------
// Parameters: HWND hdlg Handle of dialog wnd
// NPPICTUREDATA pPictureData -> to PICTUREDATA struct
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR UpdateInfoFileName
( HWND hdlg, NPPICTUREDATA pPictureData )
{char szBuffer[MAX_NAME_LEN + 10]; // Name buffer
char szFormat[20]; // Format buffer
lstrcpy( szFormat, "%s%s" );
if( pPictureData->wDuplicationIndex > 0 )
lstrcat( szFormat, ":%u" );
wsprintf( szBuffer, szFormat, (LPSTR) pPictureData->szPictureName,
(LPSTR) pPictureData->szPictureExt,
pPictureData->wDuplicationIndex );
AnsiUpper( szBuffer );
SetDlgItemText( hdlg, IMAGE_INFO_NAME, (LPSTR) szBuffer );
return;
}
// Function: UpdateInfoCurrentSize - Updates the current size in the
// info dialog
// --------------------- -----------------------------------------------
// Parameters: HWND hdlg Handle of dialog wnd
// NPPICTUREDATA pPictureData -> to PICTUREDATA struct
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR UpdateInfoCurrentSize
( HWND hdlg, NPPICTUREDATA pPictureData )
{char szBuffer[50]; // buffer
char szFormat[20]; // Format buffer
LoadString( ViewerQueryResources(), VIEWER_STRING_WANDH,
szFormat, sizeof( szFormat ));
wsprintf( szBuffer, szFormat,
pPictureData->rcCurPictureRect.right -
pPictureData->rcCurPictureRect.left,
pPictureData->rcCurPictureRect.bottom -
pPictureData->rcCurPictureRect.top );
SetDlgItemText( hdlg, IMAGE_INFO_CURSIZE, szBuffer );
return;
}
// Function: InitializePopupMenus - Called just before the popup menus
// are displayed
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Handle of Picture window
// HMENU hmenuPopup Handle of popup menu
// int nPopupIndex Index of popup
//
// Returns: LONG 0L if successful
// --------------------------------------------------------------------
static LONG NEAR InitializePopupMenus
( HWND hwndPicture, HMENU hmenuPopup, int nPopupIndex )
{NPPICTUREDATA pPictureData; // -> picture data struct
char szTitle[64]; // OLE Client doc title
char szItemFormat1[32]; // Item format string
char szItem1[128]; // New item string
char szItemFormat2[32]; // Item format string
char szItem2[128]; // New item string
if( !(pPictureData =
(NPPICTUREDATA) GetWindowWord( hwndPicture, 0 )))
{CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOPICDATA, VIEWER_STRING_CAPTION, MB_OK );
return 0L;
}
// Decrement index if maximized since MDI adds a system menu item
// which puts count off by one
if( IsZoomed( hwndPicture ))
nPopupIndex--;
if( nPopupIndex == MENU_FILE_POS )
{ // See if wnd is an activated client object
if( QTOLE_IsActiveObjectWnd
( ViewerQueryOleData(), hwndPicture, szTitle ))
{LoadString( ViewerQueryResources(),
VIEWER_STRING_OLECLOSE, szItemFormat1, sizeof( szItemFormat1 ));
wsprintf( szItem1, szItemFormat1, (LPSTR) szTitle );
LoadString( ViewerQueryResources(),
VIEWER_STRING_OLEEXIT, szItemFormat2, sizeof( szItemFormat2 ));
wsprintf( szItem2, szItemFormat2, (LPSTR) szTitle );
}
else
{LoadString( ViewerQueryResources(),
VIEWER_STRING_CLOSE, szItem1, sizeof( szItem1 ));
LoadString( ViewerQueryResources(),
VIEWER_STRING_EXIT, szItem2, sizeof( szItem2 ));
}
DeleteMenu( hmenuPopup, VIEWER_FILE_CLOSE, MF_BYCOMMAND );
InsertMenu( hmenuPopup, 1, MF_BYPOSITION,
VIEWER_FILE_CLOSE, szItem1 );
DeleteMenu( hmenuPopup, VIEWER_FILE_EXIT, MF_BYCOMMAND );
InsertMenu( hmenuPopup, (UINT) -1, MF_BYPOSITION,
VIEWER_FILE_EXIT, szItem2 );
}
else if( nPopupIndex == MENU_EDIT_POS )
{EnableMenuItem( hmenuPopup, VIEWER_EDIT_COPYPICTURE,
( IsIconic( hwndPicture ) ? MF_GRAYED: MF_ENABLED ) |
MF_BYCOMMAND );
EnableMenuItem( hmenuPopup, VIEWER_EDIT_OPTIONS,
( IsIconic( hwndPicture ) ) ? MF_GRAYED: MF_ENABLED );
EnableMenuItem( hmenuPopup, VIEWER_EDIT_CANCELSEL,
( IsRectEmpty( &pPictureData->qtoleOptions.rcSelection ))?
MF_GRAYED: MF_ENABLED );
}
else if( nPopupIndex == MENU_IMAGE_POS )
{CheckMenuItem( hmenuPopup, VIEWER_IMAGE_HALFSIZE,
( pPictureData->zsZoomScroll.wCurZoomIndex ==
VIEWER_IMAGE_HALFSIZE) ? MF_CHECKED: MF_UNCHECKED );
CheckMenuItem( hmenuPopup, VIEWER_IMAGE_NORMALSIZE,
( pPictureData->zsZoomScroll.wCurZoomIndex ==
VIEWER_IMAGE_NORMALSIZE) ? MF_CHECKED: MF_UNCHECKED );
CheckMenuItem( hmenuPopup, VIEWER_IMAGE_DOUBLESIZE,
( pPictureData->zsZoomScroll.wCurZoomIndex ==
VIEWER_IMAGE_DOUBLESIZE) ? MF_CHECKED: MF_UNCHECKED );
}
return 0L;
}
// Function: SetOptionsDefaults - Set option defaults
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Picture hwnd
// NPPICTUREDATA pPictureData -> picture data struct
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR SetOptionsDefaults
( HWND hwndPicture, NPPICTUREDATA pPictureData )
{ // Preset copy struct parameters that do not change
pPictureData->qtoleOptions.lStructSize = sizeof( QTOLE_OPTIONSPICTURE );
pPictureData->qtoleOptions.lVersion = VERSION_1;
pPictureData->qtoleOptions.wObjectType = PICTURE_OBJECT;
pPictureData->qtoleOptions.hwndObject = hwndPicture;
pPictureData->qtoleOptions.phPicture = pPictureData->phPicture;
// Query qtw.ini for defaults
ViewerGetDefaultOptions( &pPictureData->qtoleOptions );
lstrcpy( pPictureData->qtoleOptions.szCaption, pPictureData->szPictureName );
lstrcat( pPictureData->qtoleOptions.szCaption, pPictureData->szPictureExt );
return;
}
// Function: UpdatePictForOptions - Sets the picture according to values set
// in options struct
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Picture window handle
// NPPICTUREDATA pPictureData Picture data structure
// BOOL bCalledByOLE TRUE if called by ole callback funct.
//
// Returns: None
// --------------------------------------------------------------------
VOID FAR UpdatePictForOptions
( HWND hwndPicture, NPPICTUREDATA pPictureData, BOOL bCalledByOLE )
{LPQTOLE_OPTIONSPICTURE lpOptions;
POINT ptUL;
WORD wZoomIndex;
lpOptions = &pPictureData->qtoleOptions;
if( lpOptions->bZoomHalf )
SendMessage( hwndPicture, WM_COMMAND, VIEWER_IMAGE_HALFSIZE, 0L );
else if( lpOptions->bZoomNormal )
SendMessage( hwndPicture, WM_COMMAND, VIEWER_IMAGE_NORMALSIZE, 0L );
else if( lpOptions->bZoomDouble )
SendMessage( hwndPicture, WM_COMMAND, VIEWER_IMAGE_DOUBLESIZE, 0L );
else if( bCalledByOLE )
{wZoomIndex = ViewerQueryZoomIndex( lpOptions->wZoomCurrent );
ZoomPicture( hwndPicture, wZoomIndex );
if( !IsRectEmpty( &lpOptions->rcSelection ))
{ptUL = *(LPPOINT) &lpOptions->rcSelection.left;
ptUL.x = MulDiv( ptUL.x, (int) lpOptions->wZoomCurrent, 100 );
ptUL.y = MulDiv( ptUL.y, (int) lpOptions->wZoomCurrent, 100 );
ProcessHorzScroll( hwndPicture, SB_THUMBPOSITION, ptUL.x );
ProcessVertScroll( hwndPicture, SB_THUMBPOSITION, ptUL.y );
InvalidateRect( hwndPicture, NULL, TRUE );
}
}
return;
}
// Function: PopulateOptionsStruct - Populated the options structure
// --------------------------------------------------------------------
// Parameters: HWND hwndPicture Picture window handle
// NPPICTUREDATA pPictureData Picture data structure
//
// Returns: None
// --------------------------------------------------------------------
static VOID NEAR PopulateOptionsStruct
( HWND hwndPicture, NPPICTUREDATA pPictureData )
{ // Update these each time in case they get NULLed somewhere
pPictureData->qtoleOptions.hwndObject = hwndPicture;
pPictureData->qtoleOptions.phPicture = pPictureData->phPicture;
if( pPictureData->qtoleOptions.bZoomHalf )
pPictureData->qtoleOptions.wZoomCurrent = 50;
else if( pPictureData->qtoleOptions.bZoomNormal )
pPictureData->qtoleOptions.wZoomCurrent = 100;
else if( pPictureData->qtoleOptions.bZoomDouble )
pPictureData->qtoleOptions.wZoomCurrent = 200;
else
pPictureData->qtoleOptions.wZoomCurrent =
ViewerQueryZoomMultiplier
( pPictureData->zsZoomScroll.wCurZoomIndex );
return;
}
// The remaining functions are the query functions called by other modules
// Function: ViewerQueryActivePictureName - Query name of active picture
// --------------------------------------------------------------------
// Parameters: LPSTR lpBuffer string buffer
//
// Returns: LPSTR lpBuffer Name of active picture
// --------------------------------------------------------------------
LPSTR FAR ViewerQueryActivePictureName( LPSTR lpBuffer )
{HWND hwndPicture; // Handle to active window
NPPICTUREDATA pPictureData; // -> picture data struct
hwndPicture = (HWND) SendMessage
( ViewerQueryClientWindow(), WM_MDIGETACTIVE, 0, 0L );
*lpBuffer = 0;
if( pPictureData = (NPPICTUREDATA) GetWindowWord( hwndPicture, 0 ))
lstrcpy( lpBuffer, pPictureData->szPictureName );
return lpBuffer;
}